home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Better AD security / Source / ShowIcon.c < prev    next >
Text File  |  1996-06-21  |  8KB  |  340 lines

  1. /*    NAME:
  2.         ShowIcon.c
  3.  
  4.     WRITTEN BY:
  5.         Dair Grant, based on Peter Lewis/Jim Walker/François Pottier/
  6.         previous ShowINIT authors' work.
  7.                 
  8.     DESCRIPTION:
  9.         This code is based on various bits of icon drawing code, and
  10.         adapted to support animated icons.
  11.  
  12.     NOTES:
  13.         We use the System 7 IconSuite calls to display the appropriate icon
  14.         from our INIT code's icon family. This looks after bit depths, and
  15.         removes the need for 'cicn's for colour displays.
  16.         
  17.         If we can't use the IconSuite routines, we can only handle 'ICN#'
  18.         resources.
  19.         
  20.     ___________________________________________________________________________
  21. */
  22. //=============================================================================
  23. //        Include files
  24. //-----------------------------------------------------------------------------
  25. #include <Resources.h>
  26. #include <Icons.h>
  27. #include "ES.h"
  28. #include "ShowIcon.h"
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44. //=============================================================================
  45. //        Private function prototypes
  46. //-----------------------------------------------------------------------------
  47. unsigned short    CheckSum(unsigned short x);
  48. void            GetIconRect(Rect *theRect, Rect *thePortRect);
  49. void            NextPosition(Rect *theRect);
  50. void            PlotBWIcon(Rect *iconRect, Handle theIcon);
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66. //=============================================================================
  67. //        Private defines
  68. //-----------------------------------------------------------------------------
  69. #define    LMVCoord            (* (short*) 0x92A)        // Vertical coordinate
  70. #define    LMVCheckSum            (* (short*) 0x928)        // Vertical coordinate checksum
  71. #define    LMHCoord            (* (short*) 0x92C)        // Horizontal coordinate
  72. #define    LMHCheckSum            (* (short*) 0x92E)        // Horizontal coordinate checksum
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88. //=============================================================================
  89. //        PlotINITIcon : Plot a series of icons on the screen.
  90. //-----------------------------------------------------------------------------
  91. //        Note :    We are passed an array of icon resource IDs, the number of
  92. //                valid IDs there are in the array, the number of ticks to wait
  93. //                between showing each icon, and a status flag for the presence
  94. //                of Color Quickdraw and the IconSuite routines.
  95. //
  96. //                Usually Extensions will pass in only one icon, but this allows
  97. //                us to support animated icons as well.
  98. //
  99. //                We use the _IconSuite routines to plot the icons. These
  100. //                look after all the details of deciding what icon to use,
  101. //                depending on the depth of the display. They also work using
  102. //                the same icon families that the Finder uses, which means
  103. //                there's no need for a 'cicn' version.
  104. //
  105. //                If we don't have _IconSuite, or Colour QuickDraw, we have to
  106. //                plot an 'ICN#' icon.
  107. //-----------------------------------------------------------------------------
  108. void PlotINITIcon(Boolean useIconSuite, short animDelay, short numIcons, short (*theIcons)[])
  109. {    GrafPtr        savePort, newPort;
  110.     GrafPort    newBWPort;
  111.     CGrafPort    newColourPort;
  112.     Handle        theIconHnds[kMaxNumIcons+1];
  113.     Rect         theIconPos;
  114.     long        theTicks;
  115.     short        i;
  116.  
  117.  
  118.  
  119.     // Save the port, and open a new one
  120.     GetPort(&savePort);
  121.     if (useIconSuite)
  122.         {
  123.         OpenCPort(&newColourPort);
  124.         newPort = (GrafPtr) &newColourPort;
  125.         }
  126.     else
  127.         {
  128.         OpenPort(&newBWPort);
  129.         newPort = &newBWPort;
  130.         }
  131.     SetPort(newPort);
  132.  
  133.  
  134.  
  135.     // Work out where we should draw the icon
  136.     GetIconRect(&theIconPos, &newPort->portRect);
  137.  
  138.  
  139.     // Read in handles to as many icons as we have to/can. If we Get/Plot/Dispose
  140.     // of each icon in turn, we can get jerky animation.
  141.     for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
  142.         {
  143.         if (useIconSuite)
  144.             GetIconSuite(&theIconHnds[i], (*theIcons)[i], svAllLargeData);
  145.         else
  146.             theIconHnds[i] = GetResource('ICN#', (*theIcons)[i]);
  147.         }
  148.             
  149.  
  150.     // Plot all the icons, with the right delay
  151.     for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
  152.         {
  153.         if (useIconSuite)
  154.             PlotIconSuite(&theIconPos, atNone, ttNone, theIconHnds[i]);
  155.         else
  156.             PlotBWIcon(&theIconPos, theIconHnds[i]);
  157.         Delay(animDelay, &theTicks);
  158.         }
  159.     
  160.     
  161.     // Before releasing them again
  162.     for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
  163.         {
  164.         if (useIconSuite)
  165.             DisposeIconSuite(theIconHnds[i], true);
  166.         else
  167.             ReleaseResource(theIconHnds[i]);
  168.         }
  169.  
  170.     
  171.     // Set things up for the next INIT's icon - if we drew anything
  172.     if (numIcons > 0)
  173.         NextPosition(&theIconPos);
  174.  
  175.  
  176.     // Dispose of our temporary port, and restore the old one
  177.     if (useIconSuite)
  178.         CloseCPort(&newColourPort);
  179.     else
  180.         ClosePort(&newBWPort);
  181.     SetPort(savePort);
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198. //=============================================================================
  199. //        CheckSum : Verify that the previous INIT knew about ShowINIT Icon.
  200. //-----------------------------------------------------------------------------
  201. unsigned short CheckSum(unsigned short x)
  202. {
  203.     return((x << 1) | (x >> 15)) ^ 0x1021;
  204. }
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220. //=============================================================================
  221. //        GetIconRect : Calculate the correct position for our INIT's icon.                                                                 
  222. //-----------------------------------------------------------------------------
  223. //        Note :    We leave the correct position in theRect. We are given the
  224. //                portRect field of the current graphics port in thePortRect.
  225. //
  226. //                *theRect is forced to be onscreen. This is done by taking
  227. //                the horizontal offset modulo the screen width to generate the
  228. //                horizontal position of the icon, and the offset divided by the
  229. //                screen width to generate the proper row. This mechanism can get
  230. //                messed up if people plot icons at non-standard offsets.
  231. //
  232. //                We are also responsible for initialising the ShowInitIcon
  233. //                mechanism if we're the first INIT to load.
  234. //-----------------------------------------------------------------------------
  235. void GetIconRect(Rect *theRect, Rect *thePortRect)
  236. {
  237.  
  238.     // If we're first, initialise the mechanism for everyone else
  239.     if (CheckSum(LMHCoord) != LMHCheckSum)
  240.         LMHCoord = 8;
  241.     if (CheckSum(LMVCoord) != LMVCheckSum)
  242.         LMVCoord = thePortRect->bottom - 40;
  243.     
  244.     
  245.     
  246.     // Wrap round if we would move off the edge of the screen
  247.     if (LMHCoord + 34 > thePortRect->right)
  248.         {
  249.         theRect->left    = 8;
  250.         theRect->top    = LMVCoord - 40;
  251.         }
  252.  
  253.     // Otherwise move ourselves to the next position
  254.     else
  255.         {
  256.         theRect->left    = LMHCoord;
  257.         theRect->top    = LMVCoord;
  258.         }
  259.     theRect->right    = theRect->left + 32;
  260.     theRect->bottom    = theRect->top + 32;
  261. }
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277. //=============================================================================
  278. //        NextPosition : Advance the ShowIcon position for the next INIT.                                                                 
  279. //-----------------------------------------------------------------------------
  280. void NextPosition(Rect *theRect)
  281. {
  282.  
  283.     // Update the position for the next INIT
  284.     LMHCoord    = theRect->left + 40;
  285.     LMVCoord    = theRect->top;
  286.     LMHCheckSum    = CheckSum(LMHCoord);
  287.     LMVCheckSum    = CheckSum(LMVCoord);
  288. }
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304. //=============================================================================
  305. //        PlotBWIcon : Plot an 'ICN#' icon.
  306. //-----------------------------------------------------------------------------
  307. void PlotBWIcon(Rect *iconRect, Handle theIcon)
  308. {    BitMap        src;
  309.     GrafPtr        thePort;
  310.     
  311.     
  312.  
  313.     // Lock the icon down, if we have one
  314.     if (theIcon == nil)
  315.         return;
  316.     else
  317.         HLock(theIcon);
  318.     
  319.     
  320.     // Prepare the source and destination bitmaps
  321.     src.baseAddr = *theIcon + 128;                    // 128 byte ofset to Mask
  322.     src.rowBytes = 4;
  323.     SetRect(&src.bounds, 0, 0, 32, 32);
  324.     GetPort(&thePort);
  325.     
  326.     
  327.     // Transfer the mask
  328.     CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcBic, nil);
  329.     
  330.         
  331.     // Followed by the icon
  332.     src.baseAddr = *theIcon;                        // 0 byte offset to icon data
  333.     CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcOr, nil);
  334.  
  335.  
  336.     // Unlock the icon
  337.     HUnlock(theIcon);
  338. }
  339.  
  340.